package com.ygxsk.carhome.retrofit;

import android.text.TextUtils;

import com.blankj.utilcode.util.LogUtils;
import com.blankj.utilcode.util.Utils;
import com.ygxsk.carhome.constant.ConstantSign;
import com.ygxsk.carhome.response.HttpEntityProperty;
import com.ygxsk.carhome.utils.CommUtils;

import org.jetbrains.annotations.NotNull;

import io.reactivex.rxjava3.android.schedulers.AndroidSchedulers;
import io.reactivex.rxjava3.core.Observable;
import io.reactivex.rxjava3.core.ObservableSource;
import io.reactivex.rxjava3.core.ObservableTransformer;
import io.reactivex.rxjava3.functions.Function;
import io.reactivex.rxjava3.schedulers.Schedulers;

/*
 * @Author:itchenqi
 * @Time:2022-10-25  14:50
 * @Description:传递ApiRequestSubListener 为了做日志上传,原始的泛型标识SucceedData
 */
public class ResponseTransformer<SucceedData> implements ObservableTransformer<HttpEntityProperty<SucceedData>, SucceedData> {

    /**
     * //     * 接口的标识内容，区分是哪个接口来的
     * //
     */
//    protected int what_method;
//
//    //如果服务器的响应发生了异常，那么是展示toast还是覆盖该页面*/
//    private int responseShowPageOrToast;

//    /**
//     * 接口名的标识内容
//     */
//    protected String url_method;
//
//    /**
//     * 接口请求的方式
//     */
//    protected String request_method;
//
//    /**
//     * 接口上传的参数内容,在入口处 有拦截，能走到这里就一定不是空值。
//     */
//    protected HashMap<String, Object> hashMapParam;

    protected AddLogUpLoadInfo addLogUpLoadInfo;

    /**
     * 每个界面之中的类似Handler的监听器。
     */
    protected ApiRequestSubListener<SucceedData> apiRequestSubListener;

//原始代码,让我自己给删除了
//    public ResponseTransformer() {
//    }
    //    public static <R> ResponseTransformer<R> obtain() {
//        return new ResponseTransformer<>();
//    }

//    public static <R> ResponseTransformer<R> obtain() {
//        ResponseTransformer responseTransformer = new ResponseTransformer(what_method,name_method,hashMapParam,apiRequestSubListener);
//        return new ResponseTransformer<>(what_method,name_method,hashMapParam,apiRequestSubListener);
//    }

    public ResponseTransformer(AddLogUpLoadInfo _addLogUpLoadInfo,//
                               ApiRequestSubListener<SucceedData> _apiRequestSubListener) {
        this.addLogUpLoadInfo = _addLogUpLoadInfo;
        this.apiRequestSubListener = _apiRequestSubListener;
    }

    @NotNull
    @Override
    public ObservableSource<SucceedData> apply(@NotNull Observable<HttpEntityProperty<SucceedData>> upstream) {

        return upstream.onErrorResumeNext(new Function<Throwable, ObservableSource<? extends HttpEntityProperty<SucceedData>>>() {

                    @Override
                    public ObservableSource<? extends HttpEntityProperty<SucceedData>> apply(@NotNull Throwable throwable) throws Exception {

//                        LogUtils.d(ConstantSign.LOGCAT_NOMAL + "--------onErrorResumeNext---------apply------>执行的是-->" + addLogUpLoadInfo.getUrlPath());
                        //itchen->--------onErrorResumeNext---------apply------>执行的是-->/auth/v1/shop/comboconsumed/getListForEmployeeEnd

                        //这种类的日志也走到了这里。
                        //{"data":"","message":"密码错误！","code":"20211"}

                        if (throwable != null) {
                            //这个日志不完整
                            //LogUtils.d(ConstantApi.LOGCAT_NOMAL + "ResponseTransformer请求中间报错-->" + throwable.getLocalizedMessage());
                            //打印报错的日志信息;
//                            if (addLogUpLoadInfo != null) {
//                                LogUtils.d("itchenqi---接口名#" + addLogUpLoadInfo.getUrlPath() + "#-------------------Throwable--->" + throwable.getClass().getName() + "#" + throwable.getLocalizedMessage());
//                            }

                            // : 2022-10-26 17:11 这种代理断连的怎么办
                            //itchenqi---接口名#stage-api/home/getAppHomeData/#-------------------Throwable--->retrofit2.adapter.rxjava3.HttpException#HTTP 502 Bad Gateway

                            // : 2022-11-02 21:17 发送到界面上 去处理界面的异常 这里 也要判断是否关闭了日志开关
//                            if (MMKV.defaultMMKV().decodeBool(ConstantSign.MMKV_ADDLOG_SUCCESSED)) {
                            if (apiRequestSubListener != null) {
                                apiRequestSubListener.addLogInApiRequestListener(Utils.getApp(),//
                                        addLogUpLoadInfo.getUrlPath(),//
                                        addLogUpLoadInfo.getRequestMethod(),//这里的报错上传get或者post无所谓,暂时也写上
                                        addLogUpLoadInfo.getHashMapParameter(),//
                                        "onErrorResumeNext之中的-" + CommUtils.addLogFormatException((Exception) throwable));
                            }
//                            }
//                        else {
//                            LogUtils.d(ConstantApi.LOGCAT_NOMAL + "upstream.onErrorResumeNext--之中发现日志开关是 关闭的 MMKV_ADDLOG_SUCCESSED 值是false");
//                        }

                        }

                        return Observable.error(new ApiException(//是一个代替，若以上出异常就走这里
                                ConstantSign.REQUEST_30003, //
                                (ApiService.IS_DEBUG) ? throwable.getClass().getName() + "#" + throwable.getLocalizedMessage() : ConstantSign.REQUEST_30003_TEXT,//
                                addLogUpLoadInfo,//
                                apiRequestSubListener));

                    }

                }).flatMap(new Function<HttpEntityProperty<SucceedData>, ObservableSource<SucceedData>>() {//

                    @Override
                    public ObservableSource<SucceedData> apply(@NotNull HttpEntityProperty<SucceedData> responseData) throws Exception {

                        LogUtils.d(ConstantSign.LOGCAT_NOMAL + "---flatMap----apply------>即将执行-->【" + addLogUpLoadInfo.getUrlPath() + "】");

                        if (responseData != null) {

                            if (TextUtils.equals(ConstantSign.RESPONSE_20000, responseData.getCode())) {//如果是20000就是数据请求成功

//                                if (addLogUpLoadInfo != null) {
                                //LogUtils.d(ConstantSign.LOGCAT_NOMAL + "【-" + addLogUpLoadInfo.getUrlPath() + "-】#-----------------------------数据请求-响应200-成功----------------------------------------#");
//                                    if (addLogUpLoadInfo.getActivity() instanceof Activity) {
//                                        apiRequestSubListener.beforeSuccessDataDoSomething(
//                                                addLogUpLoadInfo.getWhat(), //
//                                                responseData.getCode(),//
//                                                responseData.getMessage());//
//                                    }
//                                }

                                //在处理20000的数据之前 需要处理的内容
                                //LogUtils.d("itchen-20000 的数据-responseData->" + responseData.toString());
                                //HttpEntitySK{code='200', msg='操作成功', data=null}

                                if (responseData.getData() != null) {//数据是20000但是responseData.getData()不是空值

                                    //返回的有效信息 successData 不是空，那么直接响应过去
                                    //LogUtils.d(ConstantSign.LOGCAT_NOMAL + "data是空值");

                                    return Observable.just(responseData.getData());//

                                } else {
                                    //数据是20000但 responseData.getData()是空值/或者空列表/或者空对象/空字符串等情况

                                    LogUtils.d(ConstantSign.LOGCAT_NOMAL + "responseData.getData()是空的-拦截要上传的日志");

                                    //这里需要上传个日志信息--因为返回来的  有效数据SuccessData 信息为空
//                                    if (MMKV.defaultMMKV().decodeBool(ConstantSign.MMKV_ADDLOG_SUCCESSED)) {

                                    if (apiRequestSubListener != null) {
                                        // : 2022-11-02 21:18 其实这里也可以处理空间面的 内容  发送到主界面 ，
                                        apiRequestSubListener.addLogInApiRequestListener(//
                                                addLogUpLoadInfo.getActivity(),//上下文对象
                                                addLogUpLoadInfo.getUrlPath(),//接口名称
                                                addLogUpLoadInfo.getRequestMethod(),//人为的手动传入是get还是post
                                                addLogUpLoadInfo.getHashMapParameter(),//接口上传的参数
                                                "successData=是空值"//
                                                        + responseData.toString());//后台返回来的，不是正常的code携带的消息。//

                                    }

//                                    }

                                    return Observable.just(responseData.getData());//原始值

                                }

                            } else {//非20000的数据

//                                LogUtils.d(ConstantSign.LOGCAT_NOMAL + "即将上传日志-非200-里边的数据-responseData.toString()->" + responseData.toString());

                                //---------------------------------------------------------------------------
                                //每个接口可能有它自己的单独的接口报错的处理-只负责处理界面
                                //---------------------------------------------------------------------------
                                //上传日志就在子线程之中就行，暂时不处理
//                                if (MMKV.defaultMMKV().decodeBool(ConstantSign.MMKV_ADDLOG_SUCCESSED)) {
//                                    LogUtils.d(ConstantApi.LOGCAT_NOMAL + "上传日志 是打开的，可再上传");
                                if (apiRequestSubListener != null) {
                                    if (addLogUpLoadInfo != null) {
                                        apiRequestSubListener.addLogInApiRequestListener(//
                                                addLogUpLoadInfo.getActivity(),//上下文对象
                                                addLogUpLoadInfo.getUrlPath(),//接口名称
                                                addLogUpLoadInfo.getRequestMethod(),//人为的手动传入是get还是post
                                                addLogUpLoadInfo.getHashMapParameter(),//接口上传的参数
                                                "responseData.getMessage()=>" + responseData.getMessage()//
                                                        + "#allData=>" + responseData.toString());//后台返回来的，不是正常的code携带的消息。
                                    }
                                }
//                                }
//                                else {
//                                    LogUtils.d(ConstantApi.LOGCAT_NOMAL + "-MMKV_ADDLOG_SUCCESSED =的值是false");
//                                }
                                //---------------------------------------------------------------------------

                                //请求异常,报错的code和报错的message  2022-10-27 添加
                                return Observable.error(new ApiException(//这是一个代替，如果以上出异常就走这里
                                        responseData.getCode(), //直接string不用再次转换
                                        responseData.getMessage(),//"测试到-Observable.error-->" +
                                        addLogUpLoadInfo,//
                                        apiRequestSubListener));
                            }

                        } else {
                            //responseData ==null- 一般走不到这里来；
//                            LogUtils.d(ConstantSign.LOGCAT_NOMAL + "一般不会走到-responseData ==null-这里来");
                            //---------------------------------------------------------------------------------------------
                            try {
                                //do
                                //上传日志信息
//                                if (MMKV.defaultMMKV().decodeBool(ConstantSign.MMKV_ADDLOG_SUCCESSED)) {
                                if (apiRequestSubListener != null) {
                                    //这里要做上传日志的处理--暂时就放在子线程之中处理
                                    if (addLogUpLoadInfo != null) {
                                        apiRequestSubListener.addLogInApiRequestListener(//
                                                addLogUpLoadInfo.getActivity(),//上下文对象
                                                addLogUpLoadInfo.getUrlPath(),//接口名称
                                                addLogUpLoadInfo.getRequestMethod(),//人为的手动传入是get还是post
                                                addLogUpLoadInfo.getHashMapParameter(),//接口上传的参数
                                                "responseData是空值~"//单纯的私人的消息，不是正常的code携带的消息。
                                        );
                                    }
                                }
//                                }
                            } catch (Exception e) {
                                //catch
                                e.printStackTrace();
                            }

                            //---------------------------------------------------------------------------------------------
                        }

                        //请求异常,报错的code和报错的message  2022-10-27 添加
                        return Observable.error(new ApiException(//这是一个代替，如果以上 真的响应数据为空 就走这里
                                responseData.getCode(), //
                                responseData.getMessage(),//
                                addLogUpLoadInfo,//
                                apiRequestSubListener));//

                    }

                }).subscribeOn(Schedulers.io())//维护有线程池
                .observeOn(AndroidSchedulers.mainThread());//主线程处理
    }
}

